<template>
  <el-dialog class="public-dialog" title="批量导入" :modelValue="dialogVisible" align-center width="1000" @close="handleClose" :close-on-click-modal="false">
    <div class="grid grid-cols-3 py-[6px] h-[100px]">
      <div v-for="item in stepsOpt" :key="item.value" class="flex items-center justify-center">
        <div class="text-[#fff] bg-[#e6e7e9] h-[24px] w-[24px] text-center font-bold text-[16px]" :class="item.value == steps ? 'bg-[#3487ff]' : ''">
          {{ item.value }}
        </div>
        <div class="ml-[8px]">{{ item.label }}</div>
      </div>
    </div>

    <div v-if="steps == 1" class="h-[400px]">
      <div class="flex border-[#e6e7e9] border-[1px] rounded-[4px] h-[120px]">
        <div class="w-[120px] bg-[#e6e7e9] flex items-center justify-center">
          <div class="dk-iconfont icon-Download" style="font-size: 50px !important"></div>
        </div>
        <div class="flex-1 p-[8px]">
          <div class="text-[16px] mb-[4px] font-bold">填写导入数据信息</div>
          <div class="text-[#666]">请按照数据模板的格式准备导入数据，模板中的表头名称不可更改，表头行不能删除</div>
          <a :href="downloadUrl" class="cursor-pointer">
            <div class="text-[#3366F1] flex items-center gap-1 mt-[4px]">下载模板</div>
          </a>
        </div>
      </div>

      <div class="flex border-[#e6e7e9] border-[1px] rounded-[4px] h-[120px] mt-[60px]" v-loading="loadings.submit">
        <div class="w-[120px] bg-[#e6e7e9] flex items-center justify-center">
          <div class="dk-iconfont icon-UploadFilled" style="font-size: 50px !important"></div>
        </div>
        <div class="flex-1 p-[8px]">
          <div class="text-[16px] mb-[4px] font-bold">上传填好的信息表</div>
          <div class="text-[#666]">文件后缀名必须为xls 或xlsx （即Excel格式），文件大小不得大于10M，最多支持导入3000条数据</div>
          <el-upload
            ref="uploadRef"
            v-model:file-list="fileList"
            accept=".csv,.xml,.xlsx"
            class="v-import mt-[4px]"
            :data="extraData"
            :action="ossParams.host ? `${ossParams.host}` : ''"
            :limit="1"
            :auto-upload="false"
            :on-exceed="handleExceed"
            :before-upload="beforeUpload"
            :on-error="handleUploadError"
            :on-success="handleUploadSuccess"
          >
            <div class="text-[#3366F1] flex items-center">上传文件</div>
          </el-upload>
        </div>
      </div>
    </div>

    <div v-if="steps == 2">
      <div>
        正常数据：<span class="mr-[16px] text-green">{{ previewData.correct_num }}条</span> 异常数据：<span class="text-red">{{ previewData.wrong_num }}条</span>
      </div>

      <vxe-grid ref="tableRef" v-bind="tableOptions" class="log-table">
        <template #NO="{ row, rowIndex }">
          <div class="flex items-center">
            <el-tooltip effect="dark" :content="row.err_msg" placement="right-start" v-if="row.err_msg">
              <div class="dk-iconfont icon-Hint text-red mr-[4px]"></div>
            </el-tooltip>
            {{ rowIndex + 1 }}
          </div>
        </template>
      </vxe-grid>
    </div>

    <div v-if="steps == 3" class="text-center h-[400px]">
      <div class="dk-iconfont icon-Check text-green mb-[20px]" style="font-size: 50px !important"></div>
      <p class="mb-[16px]">批量导入完成</p>
      <p class="mb-[16px]">
        导入成功：<span class="text-green font-bold">{{ saveData.success_num }}条</span>
      </p>
      <p class="mb-[16px]">
        导入失败：<span class="text-red font-bold">{{ saveData.failed_num }}条</span>
      </p>
      <el-link type="primary" @click="exportToExcel">下载导入结果</el-link>
    </div>

    <template #footer>
      <!-- 第一步 -->
      <template v-if="steps == 1">
        <el-button @click="handleClose">取消</el-button>
        <el-button type="primary" :loading="loadings.submit" :disabled="!fileList.length" @click="submit">下一步</el-button>
      </template>

      <!-- 第二步 -->
      <template v-if="steps == 2">
        <el-button @click="resetUpload">重新上传</el-button>
        <el-button type="primary" :loading="loadings.submit" :disabled="!tableOptions.data.length" @click="submitSave">导入</el-button>
      </template>

      <!-- 第三步 -->
      <template v-if="steps == 3">
        <el-button @click="resetUpload">重新上传</el-button>
        <el-button type="primary" @click="handleClose(1)">关闭</el-button>
      </template>
    </template>
  </el-dialog>
</template>

<script setup>
import api from "./api"

import { ElMessage, ElMessageBox, genFileId, ElNotification } from "element-plus"
import { ref } from "vue"
const load = ref(false)

import { uploadSignUrl } from "@/api/public"

const dialogVisible = ref(false)
const downloadUrl = ref("")

const props = defineProps({
  modelValue: { type: Boolean, default: "" },
  importUrl: { type: String, default: "" },
  callBack: {
    type: Function,
    default: (query) => query,
  },
  tplName: { type: String, default: "" },
})

// 步骤
const steps = ref("1")
const stepsOpt = [
  { label: "上传文件", value: "1" },
  { label: "数据预览", value: "2" },
  { label: "导入数据", value: "3" },
]
// 重新上传  重置数据
const resetUpload = () => {
  steps.value = "1"
  uploadRef?.value?.clearFiles()
  for (const key in extraData.valye) {
    extraData.valye[key] = ""
  }
  tableOptions.data = []
}

const tableOptions = reactive({
  height: "400px",
  border: "full",
  scrollY: { enabled: true },
  columns: [
    { title: "序号", width: 160, slots: { default: "NO" } },
    { field: "order_sn", title: "系统订单号（必填）", width: 150 },
    { field: "primary_cause", title: "一级退款原因（必填）", width: 170 },
    { field: "secondary_cause", title: "二级退款原因（必填）", width: 170 },
    { field: "refund_amount", title: "退款金额（必填）", width: 150 },
    { field: "refund_amount", title: "含税金额", width: 100 },
    { field: "is_dispute", title: "存在纠纷（必填）", width: 150 },
    { field: "dispute_type", title: "纠纷类型", width: 100 },
    { field: "is_cut_payment", title: "是否扣款", width: 100 },
    { field: "cargo_handler", title: "货物处理", width: 100 },
    { field: "return_warehouse", title: "退件仓库", width: 100 },
    { field: "is_generate_return", title: "是否自动生成退件单", width: 150 },
    { field: "tracking_number", title: "退件追踪号", width: 100 },
    { field: "is_api_refund", title: "是否API退款（必填）", width: 150 },
    { field: "platform_refund_reason", title: "平台退款原因", width: 100 },
    { field: "customer_refund_description", title: "客户退款描述（必填）", width: 150 },
  ],
  // platform_refund_reason primary_cause
  data: [],
})

let loadings = reactive({})
let ossParams = reactive({
  host: "",
})
const emit = defineEmits(["close", "update:modelValue"])

const fileList = ref([])
const uploadRef = ref()
const extraData = reactive({})
const fileName = ref("")
// 当超出限制
const handleExceed = (files) => {
  uploadRef.value?.clearFiles()
  const file = files[0]
  file.uid = genFileId()
  uploadRef.value?.handleStart(file)
}

const get_suffix = (name) => {
  const pos = name.lastIndexOf(".")
  let suffix = ""
  if (pos != -1) {
    suffix = name.substring(pos)
  }
  return suffix
}

const beforeUpload = (file) => {
  if (file.size > 1024 * 1024 * 1024) {
    ElMessage.warning("上传文件大小不能超过1G")
    loadings.submit = false
    return false
  }
  try {
    const { policy, accessid, dir, signature } = ossParams || {}
    const name = `${file.name.split(".")[0]}_${new Date().getTime()}`
    const _fileName = name + get_suffix(file.name)
    extraData.key = dir + _fileName
    extraData.oss_url = props.importUrl + _fileName
    extraData.policy = policy
    extraData.OSSAccessKeyId = accessid
    extraData.signature = signature
    fileName.value = _fileName
    // 第二步
    stepsTo2()
    return true
  } catch (err) {
    fileName.value = ""
    ElMessage.error(err.message)
    loadings.submit = false
    return false
  }
}
const previewData = ref({
  correct_num: 0,
  wrong_num: 0,
})
const stepsTo2 = () => {
  setTimeout(() => {
    uploadRef.value.clearFiles()
    api.importPreview({ oss_url: extraData.oss_url }).then((res) => {
      steps.value = "2"
      tableOptions.data = res.data.origin_data
      previewData.value.correct_num = res.data.correct_num
      previewData.value.wrong_num = res.data.wrong_num
      loadings.submit = false
    })
  }, 1000)
}

const handleUploadSuccess = () => {
  console.error("ar", arguments)
}
const handleUploadError = (err) => {
  fileName.value = ""
  ElMessage.error(`上传失败 ${err.toString()}`)
}

// 关闭弹窗
const handleClose = (refresh) => {
  resetUpload()
  loadings.submit = false
  fileList.value = []
  dialogVisible.value = false
  if (refresh == 1) props.callBack()
}

// 导入 预览
const submit = async () => {
  loadings.submit = true
  try {
    await initUpload()
    await uploadRef.value.submit()
    setTimeout(() => {
      loadings.submit = false
    }, 30000)
  } catch (error) {
    loadings.submit = false
  }
}

const saveData = ref({
  failed_num: 0,
  success_num: 0,
})
// 导入数据
const submitSave = () => {
  loadings.submit = true
  api
    .refundImport({ oss_url: extraData.oss_url })
    .then((res) => {
      steps.value = "3"
      saveData.value = res.data
    })
    .finally(() => {
      loadings.submit = false
    })
}
const exportData = ref([
  { name: "张三", email: "zhangsan@example.com" },
  { name: "李四", email: "lisi@example.com" },
])
import action from "@/utils/action.js"
// import { saveAs } from "file-saver"
import * as XLSX from "xlsx"
const exportToExcel = () => {
  action.setGlobalState({
    changeMicoTabsPath: {
      path: "/user/profile",
      type: "push",
    },
  })

  // // 创建工作簿

  // let excelGS = {
  //   order_sn: "系统订单号（必填）",
  //   primary_cause: "一级退款原因（必填）",
  //   secondary_cause: "二级退款原因（必填）",
  //   refund_amount: "退款金额（必填）",
  //   refund_amount: "含税金额",
  //   is_dispute: "存在纠纷（必填）",
  //   dispute_type: "纠纷类型",
  //   is_cut_payment: "是否扣款",
  //   cargo_handler: "货物处理（必填）",
  //   is_generate_return: "自动生成退件单",
  //   tracking_number: "退件追踪号",
  //   is_api_refund: "是否API退款（必填）",
  //   platform_refund_reason: "平台退款原因",
  //   customer_refund_description: "客户退款描述（必填）",
  //   err_msg: "导入结果",
  // }
  // let tableData = []
  // console.log(tableOptions.data)
  // tableOptions.data?.forEach((item) => {
  //   let row = {}
  //   for (let key in item) {
  //     if (excelGS[key]) {
  //       row[excelGS[key]] = item[key]
  //     }
  //   }
  //   tableData.push(row)
  // })
  // console.log(tableData)
  // const ws = XLSX.utils.json_to_sheet(tableData)
  // // 创建工作簿并添加工作表
  // const wb = XLSX.utils.book_new()

  // // 把表格的表头替换为对应的汉字
  // for (let key in ws) {
  //   if (ws.hasOwnProperty(key)) {
  //     if (excelGS[ws[key].v]) {
  //       ws[key].v = excelGS[ws[key].v]
  //     }
  //   }
  // }

  // XLSX.utils.book_append_sheet(wb, ws, "Sheet1")
  // // 设置列宽
  // const ws_cols = [
  //   { wch: 20 }, // 列1宽度为20个字符宽度
  //   { wch: 15 }, // 列2宽度为15个字符宽度
  //   { wch: 25 }, // 列3宽度为25个字符宽度
  //   { wch: 15 }, // 列2宽度为15个字符宽度
  //   { wch: 20 }, // 列2宽度为15个字符宽度
  //   { wch: 20 }, // 列2宽度为15个字符宽度
  //   { wch: 15 }, // 列2宽度为15个字符宽度
  //   { wch: 15 }, // 列2宽度为15个字符宽度
  //   { wch: 15 }, // 列2宽度为15个字符宽度
  //   { wch: 15 }, // 列2宽度为15个字符宽度
  //   { wch: 15 }, // 列2宽度为15个字符宽度
  //   { wch: 15 }, // 列2宽度为15个字符宽度
  //   { wch: 25 }, // 列2宽度为15个字符宽度
  // ]
  // ws["!cols"] = ws_cols

  // // 生成Excel文件
  // const wbout = XLSX.write(wb, { bookType: "xlsx", type: "binary" })

  // // 字符串转ArrayBuffer
  // function s2ab(s) {
  //   const buf = new ArrayBuffer(s.length)
  //   const view = new Uint8Array(buf)
  //   for (let i = 0; i !== s.length; ++i) view[i] = s.charCodeAt(i) & 0xff
  //   return buf
  // }

  // // 保存文件
  // saveAs(new Blob([s2ab(wbout)], { type: "application/octet-stream" }), "退款单导入结果.xlsx")
}

onMounted(() => {
  getTpl()
})
// 获取导入模板
const getTpl = async () => {
  const res = await api.getImportTpl({ tpl_name: props.tplName })
  downloadUrl.value = res.data.url
}
// 获取 oss配置
const initUpload = async () => {
  const { data } = await uploadSignUrl({ dir: props.importUrl })
  ossParams = { ...data?.signature }
}
const open = async (params = {}) => {
  dialogVisible.value = true
  initUpload()
}
defineExpose({
  open,
  handleClose,
})
</script>

<style lang="scss" scoped>
.v-import {
  :deep(.el-upload-list) {
    margin-top: 4px;
  }
}
.font-50 {
  width: 50px;
  height: 50px;
  svg {
    width: 50px;
    height: 50px;
  }
}
:deep(.el-upload-list__item) {
  background: #e6e7e9;
}
</style>
